const proxys = [];

// object proxy
const objectProxy = new Proxy({}, {
    get: function (obj, prop, receiver) {
        console.log(`get ${prop} through proxy ${proxys.indexOf(receiver) + 1}`);
        return obj[prop];
    },
    set: function (obj, prop, value, receiver) {
        obj[prop] = value;
        console.log(`set ${prop} = ${value} through proxy ${proxys.indexOf(receiver) + 1}`);
    },
    has: function (obj, prop) {
        console.log(`check ${prop} through proxy`);
        return prop in obj;
    }
});
proxys.push(objectProxy);
objectProxy.a = 1;
console.log(objectProxy.a, objectProxy.b, 'b' in objectProxy);

// property proxy
const propertyProxy = new Proxy({}, {
    deleteProperty: function (obj, prop) {
        const success = prop in obj;
        console.log(`delete ${prop} through proxy`);
        delete obj[prop];
        return success;
    },
    defineProperty: function (obj, prop, descriptor) {
        const success = Object.getOwnPropertyDescriptor(obj, prop)?.configurable || true;
        console.log(`define ${prop} with ${descriptor}`);
        if (success) {
            Object.defineProperty(obj, prop, descriptor);
        }
        return success;
    },
    ownKeys: function (obj) {
        console.log(`get propertys through proxy`)
        return Object.keys(obj);
    }
});
delete propertyProxy.a;
propertyProxy.a = 2;
delete propertyProxy.a;

// cancel proxy
const { proxy, revoke } = Proxy.revocable({}, {});
proxy.name = 'Tom';
revoke();
console.log(proxy.name);
